﻿using System;
using System.Collections.Generic;
using System.Linq;
using AnimationPackerEngine.Animation;
using AnimationPackerEngine.Animation.CommandWriters;
using Microsoft.Xna.Framework;

namespace AnimationPackerEngine
{
    public class ProcessingFrame : IComparable
    {
        public string Filename;
        public System.Drawing.Size Size;
        public System.Drawing.Bitmap Bitmap;
        public Rectangle AtlasRect;

        #region IComparable Members
        public int CompareTo(object obj)
        {
            if (obj is ProcessingFrame)
            {
                ProcessingFrame other = (ProcessingFrame)obj;

                // according to the Arevalo packing notes, selecting for the largest dimension
                // gives the best results

                int longest = Math.Max(Size.Width, Size.Height);
                int shortest = Math.Min(Size.Width, Size.Height);

                int otherLongest = Math.Max(other.Size.Width, other.Size.Height);
                int otherShortest = Math.Min(other.Size.Width, other.Size.Height);

                if (longest == otherLongest)
                {
                    if (shortest == otherShortest)
                    {
                        return 0;
                    }
                    else
                    {
                        return -(shortest.CompareTo(otherShortest));
                    }
                }

                return -(longest.CompareTo(otherLongest));
            }

            throw new ArgumentException("Parameter [obj] is not a ProcessingFrame.");
        }
        #endregion
    };

    public class ProcessingAnimation
    {
        public ProcessingAnimation(string directory)
        {
            Name = directory.Split('\\').Last<string>();
            Frames = new List<ProcessingFrame>();
            AnimationCompiler = null;
        }

        public string Name;
        public List<ProcessingFrame> Frames;
        public AnimationCompiler AnimationCompiler;
    };

    public class ProcessingAnimationCollection : IWriterContext
    {
        public List<ProcessingAnimation> AnimationCollection { get; set; }

        public ProcessingAnimationCollection()
        {
            AnimationCollection = new List<ProcessingAnimation>();
        }

        #region IWriterContext implementation
        public string CurrentScript { get; set; }

        public Rectangle AtlasRectForFile(string filename, string curScript)
        {
            // christ. could I have made this any more confusing?
            foreach (ProcessingAnimation anim in AnimationCollection)
            {
                foreach (var rawScript in anim.AnimationCompiler.Animations)
                {
                    if (rawScript.Name.ToLower() == curScript.ToLower())
                    {
                        foreach (ProcessingFrame frame in anim.Frames)
                        {
                            if (frame.Filename.ToLower() == filename.ToLower())
                            {
                                return frame.AtlasRect;
                            }
                        }

                        // not found :[
                        return new Rectangle(0, 0, 0, 0);
                    }
                }
            }

            return new Rectangle(0, 0, 0, 0);
        }

        public int ScriptIndex(string scriptName)
        {
            int idx = 0;
            foreach (ProcessingAnimation anim in AnimationCollection)
            {
                foreach (AnimationCompiler.RawAnimationScript script in anim.AnimationCompiler.Animations)
                {
                    if (script.Name.ToLower() == scriptName.ToLower())
                    {
                        return idx;
                    }

                    ++idx;
                }
            }

            return -1;
        }
        #endregion
    }
}
